#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<time.h>

#define ROWS 11
#define COLS 11

#define NUM 10

void SetMine(char board[ROWS][COLS], int row, int col) {
	srand((unsigned int)time(NULL));
	int count = NUM;

	while (count) {
		int x = rand() % row + 1;
		int y = rand() % row + 1;
		if (board[x][y] == ' ') {
			board[x][y] = '1';
			//放置以后才--
			count--;
		}
	}
}

static int GetMine(char mine[ROWS][COLS], int x, int y) {
	//周围一圈位置的ASCII码值相加 减去八个'0'的ASCII码
	return	mine[x - 1][y - 1] + mine[x - 1][y] + mine[x - 1][y + 1] 
		+ mine[x][y - 1] + mine[x][y + 1] 
		+ mine[x + 1][y - 1] + mine[x + 1][y] + mine[x + 1][y + 1] 
		- ('0' * 8);
}

int EndMine(char show[ROWS][COLS], int row, int col) {
	//统计没被排查点的个数，如果个数等于雷的个数 说明排查完毕

	int count = 0;
	for (int i = 0; i < row; ++i) {
		for (int j = 0; j < col; ++j) {
			if (show[i][j] == '*') {
				count++;
			}
		}
	}

	if (count == NUM) {
		return 1;
	}
	else {
		return 0;
	}
}


void ExpandBlank(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)
{
	int num = GetMine(mine, x, y);//九宫格雷的数量函数
	if (num)
	{
		// 将雷的数量放入show数组中， + ‘0’是将num由int类型转换为字符char类型
		show[x][y] = num + '0';
	}
	else if (show[x][y] == '*')
	{
		show[x][y] = ' ';//将没有雷的地方赋值为空格
		int i = 0, j = 0;//使用循环作为递归的条件，找出无雷区域
		for (i = x - 1; i <= x + 1; i++)
		{
			for (j = y - 1; j <= y + 1; j++)
			{
				ExpandBlank(mine, show, i, j);
			}
		}
	}
}


//int main() {
//	return 0;
//}
//
//
//void test(const char* str) {
//
//}
//
//int main() {
//
//
//	char str[] = {'a','b','c'};
//
//	printf("%zu", strlen(*str));
//
//	int c = 'a';
//
//	char* str = c;
//
//
//	test(c);
//
//	return 0;
//}


//#include <stdio.h>
//
//#define ROW 3
//#define COL 3
//
//int isFull(char arr[ROW][COL], int row, int col) {
//    for (int i = 0; i < row; ++i) {
//        for (int j = 0; j < col; ++j) {
//            //有一个空格，说明没满
//            if (arr[i][j] == ' ') {
//                return 0;
//            }
//        }
//    }
//
//    return 1;
//}
//
//char isWin(char arr[ROW][COL], int row, int col) {
//
//    for (int i = 0; i < row; ++i) {
//        if (arr[i][0] == arr[i][1] && arr[i][1] == arr[i][2] && arr[i][0] != ' ') {
//            return arr[i][0];
//        }
//    }
//
//    for (int i = 0; i < col; ++i) {
//        if (arr[0][i] == arr[1][i] && arr[1][i] == arr[2][i] && arr[0][i] != ' ') {
//            return arr[0][i];
//        }
//    }
//
//    if (arr[0][0] == arr[1][1] && arr[1][1] == arr[2][2] && arr[0][0] != ' ') {
//        return arr[0][0];
//    }
//
//    if (arr[2][0] == arr[1][1] && arr[1][1] == arr[0][2] && arr[2][0] != ' ') {
//        return arr[2][0];
//    }
//
//    if (isFull(arr, row, col) == 1) {
//        return 'q';
//    }
//
//    return 'c';
//}


//int main() {
//    //char myChar = 'a';
//    //char* myCharPointer = myChar; // 错误：不能将 char 类型的值赋给 char* 类型的变量  
//    return 0;
//}

int** generate(int numRows, int* returnSize, int** returnColumnSizes) {
	int** ret = malloc(sizeof(int*) * numRows);
	*returnSize = numRows;
	*returnColumnSizes = malloc(sizeof(int) * numRows);
	for (int i = 0; i < numRows; ++i) {
		ret[i] = malloc(sizeof(int) * (i + 1));
		(*returnColumnSizes)[i] = i + 1;
		ret[i][0] = ret[i][i] = 1;
		for (int j = 1; j < i; ++j) {
			ret[i][j] = ret[i - 1][j] + ret[i - 1][j - 1];
		}
	}
	return ret;
}

int main() {
	//一维数组
	//int a[] = { 1,2,3,4 };
	//printf("%d\n", sizeof(a));				//a sizeof(数组名)   16
	//printf("%d\n", sizeof(a + 0));			//a + 0 a是首元素地址 8
	//printf("%d\n", sizeof(*a));				//*a a是首元素地址 *a求首元素大小  4
	//printf("%d\n", sizeof(a + 1));			//a + 1 a是首元素地址 a + 1就是求第二个元素指针的大小 8
	//printf("%d\n", sizeof(a[1]));			//a[1] 首元素的大小 4
	//printf("%d\n", sizeof(&a));				//&a 整个数组的指针 指针的大小 8
	//printf("%d\n", sizeof(*&a));			//*&a == a  sizeof(数组名) 16
	//printf("%d\n", sizeof(&a + 1));			//&a + 1 &a是整个数组的地址 + 1 就是加到数组最后一个元素的后一个字节的地址 8
	//printf("%d\n", sizeof(&a[0]));			//&a[0] 第一个元素的地址 8
	//printf("%d\n", sizeof(&a[0] + 1));		//&a[0] + 1 第二个元素地址 8

	//字符数组
	char arr[] = { 'a','b','c','d','e','f' };
	printf("%d\n", sizeof(arr));			//sizeof(数组名)  6
	printf("%d\n", sizeof(arr + 0));		//arr + 0 arr是首元素地址 +0还是首元素地址 8
	printf("%d\n", sizeof(*arr));			//*arr 首元素地址解引用 首元素大小 1
	printf("%d\n", sizeof(arr[1]));			//arr[1] 第二个元素的大小 1
	printf("%d\n", sizeof(&arr));			//&arr 整个数组的地址 也就是数组大小  8
	printf("%d\n", sizeof(&arr + 1));		//整个数组的地址+1 数组最后一个元素的后一个字节的地址 8
	printf("%d\n", sizeof(&arr[0] + 1));	//第二个元素地址 8
	// 6 8 1 1 8 8 8 

	printf("%d\n", strlen(arr));			//数组的地址 由于字符数组没有 '\0' strlen在找的过程中，不知道什么时候会碰到'\0', 所以是随机值
	printf("%d\n", strlen(arr + 0));		//数组首元素地址 和第一个一样 也是随机值
	printf("%d\n", strlen(*arr));			//*arr arr是首元素地址 对arr解引用 就是'a' 'a' ASCII值为97 那么传入strlen的地址就是97 非法访问
	printf("%d\n", strlen(arr[1]));			//传入第二个元素也就是 'b', 和上一个类似 非法访问98 的地址  
	printf("%d\n", strlen(&arr));			//&arr是整个数组的地址 那么和前两个一样也是随机值
	printf("%d\n", strlen(&arr + 1));		//&arr + 1 整个数组的下一个字节地址 随机值
	printf("%d\n", strlen(&arr[0] + 1));	//第一个元素地址+1 第二个元素地址 也是随机值


	char arr[] = "abcdef";
	printf("%d\n", sizeof(arr));			//数组大小 7
	printf("%d\n", sizeof(arr + 0));		//首元素地址大小 8
	printf("%d\n", sizeof(*arr));			//首元素大小 1
	printf("%d\n", sizeof(arr[1]));			//第二个元素大小 1
	printf("%d\n", sizeof(&arr));			//整个数组指针大小 8
	printf("%d\n", sizeof(&arr + 1));		//整个数组下一个字节指针大小 8
	printf("%d\n", sizeof(&arr[0] + 1));	//第二个元素指针大小 8

	// 7 8 1 1 8 8 8
		
	printf("%d\n", strlen(arr));			//从首元素地址开始到'\0'的元素个数 6
	printf("%d\n", strlen(arr + 0));		//从首元素地址开始到'\0'的元素个数 6
	printf("%d\n", strlen(*arr));			//把第一个元素'a' 当地址传入 err 非法访问
	printf("%d\n", strlen(arr[1]));			//把第一个元素'b' 当地址传入 err 非法访问
	printf("%d\n", strlen(&arr));			//从整个数组地址开始到'\0'的元素个数 6
	printf("%d\n", strlen(&arr + 1));		//整个数组的下一个字节地址到'\0'的元素个数 随机值
	printf("%d\n", strlen(&arr[0] + 1));	//从第二个元素地址开始到'\0'的元素个数 5

	char* p = "abcdef";
	printf("%d\n", sizeof(p));			//char* 大小 8
	printf("%d\n", sizeof(p + 1));		//char* 大小 8
	printf("%d\n", sizeof(*p));			//char  大小 1
	printf("%d\n", sizeof(p[0]));		//首元素 char 大小 1
	printf("%d\n", sizeof(&p));			//char** 大小 8
	printf("%d\n", sizeof(&p + 1));		//char** 大小 8
	printf("%d\n", sizeof(&p[0] + 1));	//第二个元素 char* 大小 8

	// 8 8 1 1 8 8 8
	printf("%d\n", strlen(p));			//p指向字符串的长度 6
	printf("%d\n", strlen(p + 1));		//从字符b地址开始到'\0'的长度 5
	printf("%d\n", strlen(*p));			//传入首元素'a' 当做地址 err 非法访问
	printf("%d\n", strlen(p[0]));		//传入首元素'a' 当做地址 err 非法访问
	printf("%d\n", strlen(&p));			//传入p的地址 后面的地址未知 随机值
	printf("%d\n", strlen(&p + 1));		//传入p的地址 + 1 后面未知 随机值
	printf("%d\n", strlen(&p[0] + 1));	//传入'a'的地址 + 1 也就是b的地址 5

	// 6 5 ?????

	//二维数组
	int a[3][4] = { 0 };
	printf("%d\n", sizeof(a));					//整个数组大小 48
	printf("%d\n", sizeof(a[0][0]));			//第一个元素的第一个元素的大小 int大小 4
	printf("%d\n", sizeof(a[0]));				//第一个元素大小 int[4] 大小 16
	printf("%d\n", sizeof(a[0] + 1));			//a[0] + 1 是第一个元素的第二个元素的地址 8
	printf("%d\n", sizeof(*(a[0] + 1)));		//第一个元素的第二个元素的大小 4
	printf("%d\n", sizeof(a + 1));				//第二个元素的地址 8
	printf("%d\n", sizeof(*(a + 1)));			//第二个元素的地址解引用的大小 16
	printf("%d\n", sizeof(&a[0] + 1));			//第二个元素的地址 8
	printf("%d\n", sizeof(*(&a[0] + 1)));		//第二个元素的大小 16
	printf("%d\n", sizeof(*a));					//a没有单独在sizeof那就是第一个元素的地址，也就是
												//对第一个元素地址解引用 16
	printf("%d\n", sizeof(a[3]));				//第四个元素的大小 16 但是数组只有三个元素 越界了但是计算大小是用类型计算
	
	// 48 4 16 8 4 8 16 8 16 16 16

	return 0;
}